from nicegui import ui
from functools import partial

ui.add_css('''
    :root {
        --nicegui-default-padding: 0.5rem;
        --nicegui-default-gap: 0.5rem;
    }
    .squra{height:2em;width:2em;} 
    .use{background-color:green;}
    .unuse{background-color:Red ;}
''')

scaleX = 12
scaleY = 12
maps = [[]]


def changemaps(i,j):
    maps[i][j][2] = not maps[i][j][2]
    showmap()
ui.separator()
ui.markdown('# 热力图map conf生成器')
ui.separator()
def showmap():
    matrix.clear()
    for i in range(int(scaleY.value)):
        with ui.row().style('margin:0.5em') as line:
            for j in range(int(scaleX.value)):
                die = ui.label(maps[i][j][2]).classes('squra')
                die.style('background-color:green;'  if maps[i][j][2] else 'background-color:grey;')
                die.on('click',partial(changemaps,i,j))
        line.move(matrix)

def resetmaps():
    global maps
    maps = [[[i,j,True] for i in range(int(scaleX.value))] for j in range(int(scaleY.value))]
    showmap()

with ui.row():
    scaleX = ui.number(label='X_Scale',value=10,placeholder='横向方格数')
    scaleY = ui.number(label='Y_Scale',value=10,placeholder='纵向方格数')
    ui.button('重制映射图',on_click=resetmaps)

defaultContent = '''
[I|[vturn|[dispName|Switching Voltage (V)][dispL|!:0][dispH|!:2]
		]
	]
	[P|[Ion|[dispName|On current (A)][dispL|!:1e-6][dispH|!:1e-3][log]]
		[Ioff|[dispName|Off current (A)][dispL|!:1e-12][dispH|!:1e-6][log]]
		[OOR|[dispName|On-Off Ratio (dec)][dispL|!:1][dispH|!:10]]
		[Vth(lin.5)|[dispName|Threshold Voltage (V)][dispL|!:-2][dispH|!:2]]
		[Vth|[dispName|Threshold Voltage (V)][dispL|!:-2][dispH|!:2]]
		[Gm|[dispName|Max Transconductance (S)][dispL|!:0][dispH|!:2]]
		[SS|[dispName|Subthreshold Swing (V/dec)][dispL|!:0][dispH|!:0.5]]
	]
	[N|[Ion|[dispName|On current (A)][dispL|!:1e-6][dispH|!:1e-3][log]]
		[Ioff|[dispName|Off current (A)][dispL|!:1e-12][dispH|!:1e-6][log]]
		[OOR|[dispName|On-Off Ratio (dec)][dispL|!:1][dispH|!:10]]
		[Vth(lin.5)|[dispName|Threshold Voltage (V)][dispL|!:-2][dispH|!:2]]
		[Vth|[dispName|Threshold Voltage (V)][dispL|!:-2][dispH|!:2]]
		[Gm|[dispName|Max Transconductance (S)][dispL|!:0][dispH|!:2]]
		[SS|[dispName|Subthreshold Swing (V/dec)][dispL|!:0][dispH|!:0.5]]
	]'''
ui.separator()
with ui.grid(columns=2):
    with ui.element('div') as matrix:
        pass
    artConf = ui.code(defaultContent)
resetmaps()

ui.separator()
def posconf():
    posSeq = []
    rev = False 
    def checkline(line):
        for die in line:
            if die[2]:
                return True
        return False

    for i in reversed(range(int(scaleY.value))):
        if not checkline(maps[i]):
            continue
        listj = reversed(range(int(scaleX.value))) if rev else range(int(scaleX.value))
        for j in listj:
            if maps[i][j][2]:
                posSeq.append([j,i])
        rev = not rev

    # display positions for the config file
    from alib import alib
    unitSize=(9.0,9.0) # in millimeters
    unitStep=(10,-10)

    ret=alib('[places]')
    i=1
    for pos in posSeq:
        name=f'{i}'
        ret.setValue(f'places|{name}',f'[posBL|!:({pos[0]*unitStep[0]},{pos[1]*unitStep[1]})][size|!:{unitSize}]')
        i+=1
    
    result = alib(devices=artConf.content,
                  draw=alib("[posKey|name][pattern|(?P<type>[A-Za-z0-9]+)-.+-D(?P<place>\d+)(?P<trial>A?.*)][code|plt.axis('off')][figsize|!:(6,6)]')]"),
                  places=ret.places
    )
    print(result.ToString(''))
    return result
def showpos():
    result.content = posconf().ToString('').replace('\n','\n\n')
with ui.row():
    ui.button('生成配置文本',on_click=showpos)
    finput = ui.input(label="输入文件名",
                      value="MapForStarProbe.alib.conf",
                      placeholder="*.alib.conf")
    def saveconf():
        posconf().Save(finput.value)
    ui.button('储存配置文件',on_click=saveconf)
ui.separator()
with ui.scroll_area().classes('h-64'):
    result = ui.markdown()

ui.run()